package com.base.cn.platform.os.service.agent.settlement;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.user.AccountBizType;
import com.base.cn.platform.os.common.utils.user.AccountHistoryType;
import com.base.cn.platform.os.common.utils.user.AccountType;
import com.base.cn.platform.os.dao.agent.settlement.AgentSettlementDao;
import com.base.cn.platform.os.entity.agent.income.AgentIncome;
import com.base.cn.platform.os.entity.agent.income.AgentIncomeInfo;
import com.base.cn.platform.os.entity.agent.settlement.AgentSettlement;
import com.base.cn.platform.os.entity.agent.user.AgentUser;
import com.base.cn.platform.os.service.agent.income.AgentIncomeBiz;
import com.base.cn.platform.os.service.agent.income.AgentIncomeInfoBiz;
import com.base.cn.platform.os.service.agent.user.AgentUserBiz;
import com.base.cn.platform.os.service.manage.user.account.CusUserAccountService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 推广员结算记录Biz
 *
 * @author LIZHIPENG
 * @create 2018-05-14 下午 6:00
 */
@Service
public class AgentSettlementBiz extends BaseBiz<AgentSettlement, AgentSettlementDao> {

    @Autowired
    private AgentUserBiz agentUserBiz;
    @Autowired
    private AgentIncomeBiz agentIncomeBiz;
    @Autowired
    private AgentIncomeInfoBiz agentIncomeInfoBiz;
    @Autowired
    private CusUserAccountService cusUserAccountService;

    /**
     * 查询结算列表（分页）
     * @param page 分页
     * @param agentSettlement 条件
     * @param agentUserData 是否设置推广员数据（true：是，false：否）
     * @return
     */
    public PageInfo<AgentSettlement> querySettlementListPage(Pagination page, AgentSettlement agentSettlement, boolean agentUserData) {
        String whereSql = getWhereSql(agentSettlement);
        PageInfo<AgentSettlement> agentSettlementPageInfo = this.findPage(whereSql, page, null);
        agentSettlementPageInfo.setList(this.setExtendData(agentSettlementPageInfo.getList(), agentUserData));
        return agentSettlementPageInfo;
    }

    /**
     * 查询结算列表（不分页）
     * @param agentSettlement 条件
     * @param agentUserData 是否设置推广员数据（true：是，false：否）
     * @return
     */
    public List<AgentSettlement> querySettlementList(AgentSettlement agentSettlement, boolean agentUserData){
        String whereSql = getWhereSql(agentSettlement);
        List<AgentSettlement> agentSettlements = this.find(whereSql, agentSettlement.getCount(), null);
        return this.setExtendData(agentSettlements, agentUserData);
    }

    /**
     * 根据ID查询结算
     * @param agentSettlementId 结算ID
     * @param agentUserData 是否设置推广员数据（true：是，false：否）
     * @return
     */
    public AgentSettlement findSettlementById(BigDecimal agentSettlementId, boolean agentUserData){
        AgentSettlement agentSettlement = new AgentSettlement();
        agentSettlement.setId(agentSettlementId);
        List<AgentSettlement> agentSettlements = this.querySettlementList(agentSettlement, agentUserData);
        if(ObjectUtils.isNotEmpty(agentSettlements)){
            return agentSettlements.get(0);
        }
        return null;
    }

    /**
     * 前台确认结算方法
     * @param agentUser 分销用户对象
     * @param settlementList 每期结算记录列表
     * @param incomeInfoList 所有的收益记录列表
     * @param agentIncome 推广员总收益对象
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public void confirmSettlement(AgentUser agentUser,
                                  List<AgentSettlement> settlementList,
                                  List<AgentIncomeInfo> incomeInfoList,
                                  AgentIncome agentIncome){
        this.batchSave(settlementList);
        Map<String,List<AgentSettlement>> agentSettlementListMap = null;
        if(agentUser.getSettType()==2){//月结
            agentSettlementListMap = settlementList.stream().collect(Collectors.groupingBy(e-> DateUtils.format(e.getStartTime(),"yyyy-MM")));
        }else if(agentUser.getSettType()==3){//年结
            agentSettlementListMap = settlementList.stream().collect(Collectors.groupingBy(e-> DateUtils.format(e.getStartTime(),"yyyy")));
        }
        Map<String,List<AgentSettlement>> _agentSettlementListMap = agentSettlementListMap;
        incomeInfoList.forEach(e->{
            String key = null;
            if(agentUser.getSettType()==2){//月结
                key = DateUtils.format(e.getCreateTime(),"yyyy-MM");
            }else if(agentUser.getSettType()==3) {//年结
                key = DateUtils.format(e.getCreateTime(),"yyyy");
            }
            List<AgentSettlement> agentSettlementList =null;
            if(agentUser.getSettType()==1){
                agentSettlementList =settlementList;
            }else{
                agentSettlementList = _agentSettlementListMap.get(key);
            }
            if(ObjectUtils.isNotEmpty(agentSettlementList)){
                e.setSettlementId(agentSettlementList.get(0).getId());
            }
            e.setStatus(3);
        });
        agentIncomeInfoBiz.updateBatch(incomeInfoList);
        double rewardPrice = settlementList.stream().mapToDouble(AgentSettlement::getRewardPrice).sum();
        double spreadPrice = settlementList.stream().mapToDouble(AgentSettlement::getSpreadPrice).sum();

        agentIncomeBiz.updateById(agentIncome, null);

        //给用户账户添加金额
        if(spreadPrice > 0D){//推广收益
            cusUserAccountService.updateAccountMoney(agentUser.getUserId(),spreadPrice, AccountType.CASH.toString(), AccountHistoryType.SPREAD.getValue(),BigDecimal.ZERO,null,null,true, AccountBizType.CASH.toString(),BigDecimal.ZERO,2);
        }
        if(rewardPrice > 0D){//奖金收益
            cusUserAccountService.updateAccountMoney(agentUser.getUserId(),rewardPrice, AccountType.CASH.toString(), AccountHistoryType.REWARD.getValue(),BigDecimal.ZERO,null,null,true, AccountBizType.CASH.toString(),BigDecimal.ZERO,2);
        }
    }

    /**
     * 后台确认用户结算
     * @param agentSettlement 结算信息
     */
    /*@Transactional(rollbackFor = IllegalArgumentException.class)
    public AgentSettlement addOrUpdateSettlement(AgentSettlement agentSettlement){
        if(DataUtil.idIsNotNull(agentSettlement.getId())){
            //确认结算
            this.updateById(agentSettlement, null);
            //同步推广员总收益数据
            AgentIncome agentIncome = agentIncomeBiz.findAgentIncomeById(agentSettlement.getAgentUserId(), false);
            agentIncome.setEndIncomeSumPrice(agentIncome.getEndIncomeSumPrice() + agentSettlement.getBalancePrice());//已结算收益
            agentIncome.setNotEndIncomeSumPrice(agentIncome.getNotEndIncomeSumPrice() - agentSettlement.getBalancePrice());//未结算收益
            agentIncome.setSpreadIncomePrice(agentIncome.getSpreadIncomePrice() + agentSettlement.getSpreadPrice());//推广总收益
            agentIncome.setBountyIncomePrice(agentIncome.getBountyIncomePrice() + agentSettlement.getRewardPrice());//奖金总收益
            agentIncomeBiz.saveOrUpdateAgentIncome(agentIncome);
            //同步推广员收益明细数据
            AgentIncomeInfo agentIncomeInfo = new AgentIncomeInfo();
            agentIncomeInfo.setSettlementId(agentSettlement.getId());
            List<AgentIncomeInfo> incomeInfoList = agentIncomeInfoBiz.queryIncomeInfoList(agentIncomeInfo, false, false);
            incomeInfoList.forEach(e->e.setStatus(3));
            agentIncomeInfoBiz.updateBatch(incomeInfoList);
        }
        return agentSettlement;
    }*/


    //=============================================================
    private String getWhereSql(AgentSettlement agentSettlement){
        String whereSql = "1=1";
        if(ObjectUtils.isNotEmpty(agentSettlement)){
            if(DataUtil.idIsNotNull(agentSettlement.getId())){
                whereSql += " and id="+ agentSettlement.getId();
            }
            if(StringUtils.isNotEmpty(agentSettlement.getBeginTime())){
                whereSql += " and createTime>='"+ agentSettlement.getBeginTime() +"'";
            }
            if(StringUtils.isNotEmpty(agentSettlement.getOverTime())){
                whereSql += " and createTime<='"+ agentSettlement.getOverTime() +"'";
            }
            if(ObjectUtils.isNotEmpty(agentSettlement.getStatus())){
                whereSql += " and status="+ agentSettlement.getStatus();
            }
            if(ObjectUtils.isNotEmpty(agentSettlement.getSettlementFrom())){
                whereSql += " and settlementFrom="+ agentSettlement.getSettlementFrom();
            }
            if(DataUtil.idIsNotNull(agentSettlement.getAgentUserId())){
                whereSql += " and agentUserId="+ agentSettlement.getAgentUserId();
            }
            if(ObjectUtils.isNotEmpty(agentSettlement.getCycleNum())){
                whereSql += " and cycleNum="+ agentSettlement.getCycleNum();
            }
            if(StringUtils.isNotEmpty(agentSettlement.getAgentUserName()) || ObjectUtils.isNotEmpty(agentSettlement.getUserType())){
                AgentUser agentUser = new AgentUser();
                agentUser.setAgentUserName(agentSettlement.getAgentUserName());
                agentUser.setUserType(agentSettlement.getUserType());
                List<AgentUser> agentUsers = agentUserBiz.queryAgentUserList(agentUser, false, false, false, false);
                if(ObjectUtils.isNotEmpty(agentUsers)){
                    String agentUserIds = agentUsers.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                    whereSql += " and agentUserId in ("+ agentUserIds +")";
                }else {
                    whereSql += " and agentUserId=0";
                }
            }
        }
        whereSql += " order by id desc";
        return whereSql;
    }

    private List<AgentSettlement> setExtendData(List<AgentSettlement> agentSettlementList, boolean agentUserData){
        if(agentUserData){
            agentSettlementList = setAgentUserData(agentSettlementList, agentUserData);
        }
        return agentSettlementList;
    }

    private List<AgentSettlement> setAgentUserData(List<AgentSettlement> agentSettlementList, boolean agentUserData){
        if(ObjectUtils.isNotEmpty(agentSettlementList) && agentUserData){
            String agentUserIds = agentSettlementList.stream().map(e -> e.getAgentUserId().toString()).distinct().collect(Collectors.joining(","));
            AgentUser agentUser = new AgentUser();
            agentUser.setIds(agentUserIds);
            List<AgentUser> agentUsers = agentUserBiz.queryAgentUserList(agentUser, false, false, false, false);
            if(ObjectUtils.isNotEmpty(agentUsers)){
                for (AgentUser user : agentUsers) {
                    for (AgentSettlement agentSettlement : agentSettlementList) {
                        if(agentSettlement.getAgentUserId().equals(user.getId())){
                            agentSettlement.setAgentUser(user);
                        }
                    }
                }
            }
        }
        return agentSettlementList;
    }

}
